package com.sc.nft.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.DigitalCollectionProductInfoAuctionUserBiddingResultsVO;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.util.WeChatUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户拍卖结果表 服务实现类
 * </p>
 *
 * @author liGen
 * @since 2024-09-05
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DigitalCollectionProductInfoAuctionUserBiddingResultsServiceImpl implements DigitalCollectionProductInfoAuctionUserBiddingResultsService {

    private final DigitalCollectionProductInfoAuctionDao digitalCollectionProductInfoAuctionDao;
    private final DigitalCollectionProductInfoAuctionUserBiddingDao digitalCollectionProductInfoAuctionUserBiddingDao;
    private final DigitalCollectionProductInfoAuctionUserBiddingResultsDao digitalCollectionProductInfoAuctionUserBiddingResultsDao;
    private final Redisson redisson;
    private final DigitalCollectionProductInfoAuctionUserBiddingDetailsDao digitalCollectionProductInfoAuctionUserBiddingDetailsDao;
    private final UserCollectionDao userCollectionDao;
    private final DigitalCollectionProductInfoDao digitalCollectionProductInfoDao;
    private final ProductStockService productStockService;
    private final UserCollectionService userCollectionService;
    private final DigitalCollectionDao digitalCollectionDao;
    private final CopyrightAuctionConfigDao copyrightAuctionConfigDao;
    private final NftRegionBindingService nftRegionBindingService;
    private final UserConsensusService userConsensusService;


    /**
     * 拍卖处理
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auctionDisposal() {
        RLock lock = redisson.getLock(RedisKeyEnum.BIDDING_RESULTS_LOCK.getKey());
        try {
            boolean res = lock.tryLock(3, TimeUnit.SECONDS);
            if (!res) {
                throw new GlobalException("拍卖处理中！！！！");
            }
            CopyrightAuctionConfig auctionConfig = copyrightAuctionConfigDao.getNewOne();
            if (Objects.isNull(auctionConfig)) {
                throw new GlobalRunTimeException("拍卖处理拍卖配置为空");
            }
            Date now = new Date();
            List<DigitalCollectionProductInfoAuctionUserBiddingResults> digitalCollectionProductInfoAuctionUserBiddingResultsList = new ArrayList<>();
            // 获取活动结束未处理拍卖结果的商品
            List<DigitalCollectionProductInfoAuction> notHaveResultList = digitalCollectionProductInfoAuctionDao.getNotHaveResultList(now);
            for (DigitalCollectionProductInfoAuction digitalCollectionProductInfoAuction : notHaveResultList) {
                Long productId = digitalCollectionProductInfoAuction.getProductId();
                // 标的物价格
                BigDecimal auctionPrice = digitalCollectionProductInfoAuction.getAuctionPrice();
                // 参与藏品最低参与数量
                Integer consumptionNum = digitalCollectionProductInfoAuction.getConsumptionNum();
                // 标的物数量
                Integer auctionNum = digitalCollectionProductInfoAuction.getAuctionNum();
                List<DigitalCollectionProductInfoAuctionUserBiddingResultsVO> resultsVOList = digitalCollectionProductInfoAuctionUserBiddingDao.getResultsVOList(productId);
                // 判断是否符合最低参与数量
                for (int i = 0; i < resultsVOList.size(); i++) {
                    DigitalCollectionProductInfoAuctionUserBiddingResultsVO digitalCollectionProductInfoAuctionUserBiddingResultsVO = resultsVOList.get(i);
                    // 用户Id
                    Long userId = digitalCollectionProductInfoAuctionUserBiddingResultsVO.getUserId();
                    // 总投注数量
                    Integer biddingTotal = digitalCollectionProductInfoAuctionUserBiddingResultsVO.getBiddingTotal();

                    // 获取用户的拍卖质押物
                    List<DigitalCollectionProductInfoAuctionUserBiddingDetails> digitalCollectionProductInfoAuctionUserBiddingDetails = digitalCollectionProductInfoAuctionUserBiddingDetailsDao.
                            listByProductIdAndUserId(userId, productId);
                    List<Long> collectIds = digitalCollectionProductInfoAuctionUserBiddingDetails.stream().
                            map(DigitalCollectionProductInfoAuctionUserBiddingDetails::getRelationId).collect(Collectors.toList());
                    // 创建用户拍卖结果
                    DigitalCollectionProductInfoAuctionUserBiddingResults digitalCollectionProductInfoAuctionUserBiddingResults = new DigitalCollectionProductInfoAuctionUserBiddingResults();
                    digitalCollectionProductInfoAuctionUserBiddingResults.setProductId(productId);
                    digitalCollectionProductInfoAuctionUserBiddingResults.setUserId(userId);
                    digitalCollectionProductInfoAuctionUserBiddingResults.setBiddingTotal(biddingTotal);
                    if (i < auctionNum && biddingTotal >= consumptionNum) {
                        digitalCollectionProductInfoAuctionUserBiddingResults.setProgress(AcutionProgressEnum.WINNING_BID);
                        // 拍到
                        //销毁藏品
                        List<UserCollection> destroyList = userCollectionDao.getListByIds(collectIds);
                        for (UserCollection userCollection : destroyList) {
                            Assert.isTrue(userCollectionDao.deleteCollectionById(userCollection.getId()),()->new GlobalRunTimeException(ErrorCode.AUCTION_PLEDGE_DESTRUCTION_FAILED));
                        }
                        // 给拍卖品
                        DigitalCollectionProductInfo digitalCollectionProductInfo = digitalCollectionProductInfoDao.getById(productId);
                        // 减去拍卖商品库存
                        productStockService.subIntegralStock(productId, digitalCollectionProductInfo.getRelationId(), null, 1,
                                userId, CommodityType.AUCTION_PRODUCT);
                        DigitalCollection digitalCollection = digitalCollectionDao.getById(digitalCollectionProductInfo.getRelationId());
                        UserCollection userCollection = userCollectionService.addCollection(userId, null, digitalCollection.getId(), IdUtil.getSnowflakeNextIdStr(), digitalCollection.getCreationContent(), digitalCollection.getLevel(), digitalCollection.getFirstTitle(),
                                digitalCollection.getUserCreatorId(), ReceivedCollectionType.AUCTION, null, null, null, true, digitalCollectionProductInfo.getId(), 0L, 0L, auctionPrice, 0,null,null, AddCollectionEnum.STAIR,null,null,false);
                        // 添加拍卖成功给藏品记录
                        if(digitalCollectionProductInfo.getTypeClassify()==ClassifyType.COLLECTION&&digitalCollection.getCollectionType()==DigitalMarketTypeEnum.ECOLOGY) {
                            userConsensusService.adjustConsensusService(userId, digitalCollection.getId() ,BigDecimal.valueOf(1), UserConsensusTypeEnums.AUCTION_GET, digitalCollection.getFirstTitle(), null);
                        }
                        //更新藏品权益时间
                        nftRegionBindingService.updateNftEffectiveTime(digitalCollectionProductInfo.getRelationId());
                    } else {
                        digitalCollectionProductInfoAuctionUserBiddingResults.setProgress(AcutionProgressEnum.NO_BID);
                        // 没有拍到 藏品还原
                        userCollectionDao.updateFreezingStatusByIds(collectIds, UserCollectionFreezingStatusEnum.NORMAL);
                    }
                    digitalCollectionProductInfoAuctionUserBiddingResultsList.add(digitalCollectionProductInfoAuctionUserBiddingResults);
                }
                digitalCollectionProductInfoAuctionDao.updateHaveResult(digitalCollectionProductInfoAuction.getId(),Boolean.TRUE);
            }
            if (!CollectionUtils.isEmpty(digitalCollectionProductInfoAuctionUserBiddingResultsList)){
                digitalCollectionProductInfoAuctionUserBiddingResultsDao.saveList(digitalCollectionProductInfoAuctionUserBiddingResultsList);
            }
        } catch (Exception e) {
            WeChatUtil.sendLiGenWeChatMessage(StrUtil.format("拍卖处理失败 ,异常:{}", e.getMessage()));
            log.error("拍卖处理失败,异常:{}", e.getMessage());
            throw new GlobalRunTimeException(e.getMessage());
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}
